package com.bridgeintelligent.tag.webserver.security;

import com.bridgeintelligent.tag.constants.TagConstants;
import com.bridgeintelligent.tag.user.mgmt.pojo.User;
import com.bridgeintelligent.tag.utils.DateHelper;
import com.bridgeintelligent.tag.utils.SecurityHelper;
import com.wayneleo.quickstart.framework.IDGenerator;
import org.apache.commons.lang3.SerializationUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.util.Collection;

@Component
public class TagSessionPersistence extends EnterpriseCacheSessionDAO {

    private TagSessionMapper sessionMapper;

    public TagSessionPersistence(TagSessionMapper sessionMapper) {
        setSessionIdGenerator(sessionIdGenerator -> IDGenerator.gen());
        this.sessionMapper = sessionMapper;
    }

    @Override
    protected Serializable doCreate(Session session) {
        Serializable sessionId = generateSessionId(session);
        assignSessionId(session, sessionId);
        User user = (User) session.getAttribute(TagConstants.SESSION_KEY_OF_USER);
        if (user == null) {
            user = newGuest();
            session.setAttribute(TagConstants.SESSION_KEY_OF_USER, user);
            return sessionId;
        }
        TagSessionEntity entity = new TagSessionEntity().setId(String.valueOf(sessionId))
                                                        .setUsername(user.getUsername())
                                                        .setLoginDatetime(DateHelper.currentDateTime())
                                                        .setUpdateDatetime(DateHelper.currentDateTime())
                                                        .setSession(SerializationUtils.serialize((Serializable) session));
        sessionMapper.save(entity);
        return sessionId;
    }

    @Override
    protected void doUpdate(Session session) {
        String sessionId = String.valueOf(session.getId());
        TagSessionEntity entity = sessionMapper.findOne(sessionId);
        if (entity == null) {
            doCreate(session);
            return;
        }
        User user = (User) session.getAttribute(TagConstants.SESSION_KEY_OF_USER);
        if (user == null) {
            user = newGuest();
            session.setAttribute(TagConstants.SESSION_KEY_OF_USER, user);
        }
        if (!user.getUsername()
                 .equals(entity.getUsername())) {
            entity.setUsername(user.getUsername());
            entity.setLoginDatetime(DateHelper.currentDateTime());
        }
        entity.setUpdateDatetime(DateHelper.currentDateTime());
        entity.setSession(SerializationUtils.serialize((Serializable) session));
        sessionMapper.update(entity);
    }

    @Override
    protected void doDelete(Session session) {
        User user = (User) session.getAttribute(TagConstants.SESSION_KEY_OF_USER);
        if (user == null) {
            return;
        }
        sessionMapper.delete(String.valueOf(session.getId()));
    }

    @Override
    protected Session doReadSession(Serializable sessionId) {
        TagSessionEntity entity = sessionMapper.findOne(String.valueOf(sessionId));
        if (entity == null || entity.getSession() == null) {
            return null;
        }
        return SerializationUtils.deserialize(entity.getSession());
    }

    private User newGuest() {
        User user = new User();
        user.setUsername(SecurityHelper.guestUsername());
        user.setName("游客");
        return user;
    }

    @Override
    public void update(Session session) throws UnknownSessionException {
        doUpdate(session);
    }
//    @Override
//    public void delete(Session session) {
//        System.err.println("\n\n\n--------------->>>>>>>>>\n\n\n");
//        doDelete(session);
//    }

    @Override
    public Collection<Session> getActiveSessions() {
        return null;
    }
}
